package net.csdn.business.kanban.api.facade;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.json.JSONArray;
import cn.hutool.json.JSONObject;
import lombok.RequiredArgsConstructor;
import net.csdn.business.kanban.api.entity.Kanban;
import net.csdn.business.kanban.api.entity.KanbanField;
import net.csdn.business.kanban.api.entity.KanbanFieldExtension;
import net.csdn.business.kanban.api.entity.KanbanView;
import net.csdn.business.kanban.api.enums.*;
import net.csdn.business.kanban.api.service.*;
import net.csdn.business.kanban.common.constant.CommonConstants;
import net.csdn.business.kanban.common.constant.RedisConstants;
import net.csdn.business.kanban.common.domain.PageDto;
import net.csdn.business.kanban.common.domain.request.KanbanAddParam;
import net.csdn.business.kanban.common.domain.request.KanbanQuery;
import net.csdn.business.kanban.common.domain.request.KanbanUpdateParam;
import net.csdn.business.kanban.common.domain.resp.KanbanResp;
import net.csdn.business.kanban.common.utils.CommonConverter;
import net.csdn.business.kanban.common.utils.ObjectId;
import org.springframework.beans.BeanUtils;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Caching;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.RequestParam;

import java.util.ArrayList;
import java.util.List;

/**
 * @ClassName KanbanFacade
 * @Description TODO
 * @Author liuzhisheng
 * @Date 2023/9/18
 **/
@Service
@RequiredArgsConstructor
public class KanbanFacade {
    private final KanbanFieldService kanbanFieldService;
    private final KanbanFieldExtensionService kanbanFieldExtensionService;
    private final KanbanViewService kanbanViewService;
    private final KanbanService kanbanService;
    private final KanbanDetailService kanbanDetailService;

    /**
     * 看板列表
     * @param kanbanQuery
     * @return
     */
    public PageDto<KanbanResp> kanbanList(KanbanQuery kanbanQuery) {
        PageDto<Kanban> pageDto =  kanbanService.kanbanList(kanbanQuery);
        return CommonConverter.transferPageListEntity(pageDto,KanbanResp.class);
    }

    /**
     * 看板详情
     * @param kanbanId
     * @return
     */
    public KanbanResp getKanbanById(String kanbanId){
        Kanban kanban = kanbanService.getKanbanByObjectId(kanbanId);
        return kanban == null ? null : BeanUtil.copyProperties(kanban,KanbanResp.class);
    }

    /**
     * 新增看板
     * @param param
     * @return
     */
    @Transactional(rollbackFor = Exception.class)
    public boolean addKanban(KanbanAddParam param) {
        Kanban kanban = new Kanban();
        BeanUtils.copyProperties(param,kanban);
        kanban.setStatus(KanbanStatusEnums.OPEN.getCode());
        kanban.setCreatorId(param.getCurrUserId());
        kanban.setObjectId(ObjectId.get().toString());
        kanbanService.save(kanban);

        /**生成默认字段status*/
        KanbanField kanbanField = new KanbanField();
        kanbanField.setKanbanId(kanban.getObjectId());
        kanbanField.setFieldName(CommonConstants.FIELD_DEFAULT_NAME);
        kanbanField.setFieldType(FieldTypeEnums.SINGLE_SELECT.getCode());
        kanbanField.setUserDefined(Boolean.FALSE);
        kanbanField.setCreatorId(param.getCurrUserId());
        kanbanFieldService.save(kanbanField);

        /**Status扩展字段初始化*/
        List<KanbanFieldExtension> extensionList = new ArrayList<>();
        for (FieldStatusDefaultEnums type : FieldStatusDefaultEnums.values()) {
            KanbanFieldExtension extension = new KanbanFieldExtension();
            extension.setKanbanId(kanbanField.getKanbanId());
            extension.setFieldId(kanbanField.getId());
            extension.setCreatorId(param.getCurrUserId());
            JSONObject jsonObject = new JSONObject();
            jsonObject.set(FieldExtensionEnums.NAME.getName(), type.getName());
            jsonObject.set(FieldExtensionEnums.DESC.getName(),type.getDesc());
            jsonObject.set(FieldExtensionEnums.COLOR.getName(),type.getColor().getName());
            extension.setFieldProperties(jsonObject.toString());
            extension.setPriority(type.getSort());
            extensionList.add(extension);
        }
        kanbanFieldExtensionService.saveBatch(extensionList,extensionList.size());

        /**初始化看板view*/
        KanbanView kanbanView = new KanbanView();
        kanbanView.setKanbanId(kanban.getObjectId());
        kanbanView.setViewNumber(1);
        kanbanView.setViewName("View "+kanbanView.getViewNumber());
        kanbanView.setCreatorId(param.getCurrUserId());
        kanbanView.setPriority(1);
        kanbanView.setKanbanType(param.getKanbanType());
        JSONArray array = new JSONArray();
        for (SystemFieldEnums systemFieldEnums : SystemFieldEnums.values()) {
            JSONObject viewObject1 = new JSONObject();
            /**系统定义字段*/
            viewObject1.set(systemFieldEnums.getName(),true);
            array.add(viewObject1);
        }
        JSONObject viewObject2 = new JSONObject();
        viewObject2.set(kanbanField.getId().toString(),true);
        array.add(viewObject2);
        kanbanView.setFieldDisplayJson(array.toString());
        kanbanViewService.save(kanbanView);
        return true;
    }

    /**
     * 删除看板
     * @param kanbanId
     * @return
     */
    @Transactional(rollbackFor = Exception.class)
    @Caching(evict = {
            @CacheEvict(value = RedisConstants.KANBAN, key = "'kanban-' + #kanbanId"),
    })
    public boolean removeKanban(String kanbanId){
        /**删除看板view内的字段扩展*/
        kanbanFieldExtensionService.removeKanbanFiledExtensions(kanbanId);
        /**删除看板内的字段*/
        kanbanFieldService.removeKanbanFileds(kanbanId);
        /**删除看板内的所有view*/
        kanbanViewService.removeKanbanView(kanbanId);
        /**删除看板内明细*/
        kanbanDetailService.removeKanbanDetails(kanbanId);
        /**删除看板*/
        kanbanService.removeKanban(kanbanId);
        return true;
    }

    /**
     * 编辑看板
     * @param param
     * @return
     */
    @Caching(evict = {
            @CacheEvict(value = RedisConstants.KANBAN, key = "'kanban-' + #param.kanbanId"),
    })
    public boolean updateKanban(KanbanUpdateParam param){
        Kanban kanban = BeanUtil.copyProperties(param,Kanban.class);
        kanban.setObjectId(param.getKanbanId());
        return kanbanService.updateKanban(kanban);
    }

    /**
     * @Desc: 统计组织下的看板数量
     * @author: liuzhisheng
     * @date: 2023/10/31 11:14
     */
    public Long kanbanNumber(String orgId){
        return kanbanService.kanbanNumber(orgId);
    }
}
